package com.polaris.live.ui.party.music

import android.Manifest
import android.content.Context
import android.content.Intent
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.provider.MediaStore
import android.provider.Settings
import androidx.recyclerview.widget.LinearLayoutManager
import com.blankj.utilcode.util.ActivityUtils
import com.blankj.utilcode.util.PermissionUtils
import com.blankj.utilcode.util.StringUtils
import com.lxj.xpopup.XPopup
import com.polaris.live.R
import com.polaris.live.adapter.music.AddMusicItemAdapter
import com.polaris.live.cache.CommonCache
import com.polaris.live.common.ext.autoDp
import com.polaris.live.common.ext.setOnSingleClickListener
import com.polaris.live.common.manager.CoroutineScopeManager
import com.polaris.live.common.mvvm.base2.BaseVbFragment
import com.polaris.live.common.mvvm.viewmodel.BaseViewModel
import com.polaris.live.common.util.ToastGravity
import com.polaris.live.databinding.FragmentMusicAddBinding
import com.polaris.live.dialog.common.CommonSureDetailDialog
import com.polaris.live.translation.R.string
import com.polaris.live.ui.party.music.listener.AddMusicListener
import com.polaris.live.utils.zego.media.MediaProxy
import com.polaris.live.utils.zego.media.MusicBean
import kotlinx.coroutines.launch

/**
 * AddMusicFragment 添加音乐页面
 * @author Created by 天晴 on 2024/9/14 17:26
 * @since 1.0.0
 **/
class AddMusicFragment : BaseVbFragment<BaseViewModel, FragmentMusicAddBinding>() {

    var listener: AddMusicListener? = null

    private var isAll = false

    private var addedList: MutableList<MusicBean> = mutableListOf() //已添加
    private var unAddList: MutableList<MusicBean> = mutableListOf() //待添加

    private val emptyView by lazy {
        EmptyMusicView(requireContext()).apply {
            setEmptyTip(
                R.drawable.salalogo,
                StringUtils.getString(string.no_music),
                width = 40.autoDp,
                height = 40.autoDp,
                showAdd = false
            )
        }
    }
    private val mAdapter by lazy {
        AddMusicItemAdapter().apply {
            selectNumListener {
                isAll = it == data.count { da -> !da.haveSelect }
                setSelectAll()
                setSelectNum(it)
            }
        }
    }

    override fun initView(savedInstanceState: Bundle?) {
        mBinding.apply {
            recycler.apply {
                itemAnimator = null
                layoutManager = LinearLayoutManager(context)
                adapter = mAdapter
            }
        }
        setSelectNum(0)
        mAdapter.setEmptyView(emptyView)
        initObserve()
        initListener()

        CommonCache.getMusicList()?.let {
            addedList = it.toMutableList()
        }

        permissionStorage(requireContext(), {
            unAddList = getAllMusicFiles().toMutableList()
            val sList = unAddList.map { music ->
                val bd = addedList.any { addedItem ->
                    music.id == addedItem.id
                }
                SelectMusicBean(music, false, bd)
            }
            mAdapter.setList(sList)
        })

    }

    private fun setSelectNum(num: Int) {
        mBinding.addMusic.text = "${StringUtils.getString(string.add)} ($num)"
    }

    private fun setSelectAll() {
        if (isAll) {
            mBinding.selectImg.setImageResource(R.drawable.select_ok)
        } else {
            mBinding.selectImg.setImageResource(R.drawable.select_no)
        }

    }

    private fun initListener() {
        mBinding.close.setOnSingleClickListener {
            listener?.toBack()
        }
        mBinding.selectImg.setOnSingleClickListener {
            isAll = !isAll
            setSelectAll()
            mAdapter.allSelect(isAll)
        }

        mBinding.addRl.setOnSingleClickListener {
            val data = mAdapter.data.filter { it.select }
            if (data.isEmpty()) {
                return@setOnSingleClickListener
            }
            mAdapter.data.removeAll(data)
            mAdapter.notifyDataSetChanged()

            val sList = data.map { selectMusic -> selectMusic.music }
            unAddList.removeAll(sList)

            addedList.addAll(sList)
            MediaProxy.addMusicList(sList)

        }
    }

    private fun initObserve() {
    }

    fun setAddMusicListener(listener: AddMusicListener) {
        this.listener = listener
    }

    private fun getAllMusicFiles(): List<MusicBean> {
        val context = context ?: return mutableListOf()

        val musicList: MutableList<MusicBean> = mutableListOf()

        // 查询音频文件的列
        val projection = arrayOf(
            MediaStore.Audio.Media._ID,
            MediaStore.Audio.Media.DISPLAY_NAME,  // 音乐文件名称
            MediaStore.Audio.Media.DATA,  // 文件路径
            MediaStore.Audio.Media.DURATION,  // 音频时长
            MediaStore.Audio.Media.ARTIST, // 艺术家
            MediaStore.Audio.Media.ALBUM_ID,  // 专辑ID
        )

        // 查询条件：只包含音乐文件
        val selection = MediaStore.Audio.Media.IS_MUSIC + "!= 0"

        // 扫描音乐文件
        val cursor = context.contentResolver.query(
            MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
            projection,
            selection,
            null,
            null
        )
        if (cursor != null) {
            while (cursor.moveToNext()) {
                // 获取音乐文件信息
                val id = cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media._ID))
                val name = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DISPLAY_NAME)) ?: ""
                val path = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DATA)) ?: ""
                val duration = cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DURATION))
                val artist = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.ARTIST)) ?: ""
                val albumId = cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.ALBUM_ID))
                val music =
                    MusicBean(id, name, path, duration, artist, "content://media/external/audio/albums/$albumId")
                musicList.add(music)
            }
            cursor.close()
        }
        return musicList
    }

    /**
     * 请求本地文件权限
     */
    fun permissionStorage(
        context: Context,
        agreeBlock: () -> Unit,
        refuseBlock: () -> Unit = {
            ToastGravity.showGravity(string.please_open_file_permission)
        },
    ) {
        val permission = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
            Manifest.permission.READ_MEDIA_AUDIO
        } else {
            Manifest.permission.READ_EXTERNAL_STORAGE
        }
        val list = listOf(
            permission,
        )
        PermissionUtils.permissionGroup(
            *arrayOf(
                permission,
            )
        ).callback(object : PermissionUtils.FullCallback {
            override fun onGranted(granted: MutableList<String>) {
                if (list.size != granted.size) {
                    refuseBlock()
                } else {
                    agreeBlock()
                }
            }

            override fun onDenied(
                deniedForever: MutableList<String>,
                denied: MutableList<String>,
            ) {
                CoroutineScopeManager.mainScope.launch {
                    ToastGravity.showGravity(StringUtils.getString(string.please_open_file_permission))
                }
                refuseBlock()
                showSureDetailDialog(context)
            }
        }).request()
    }

    fun showSureDetailDialog(context: Context) {
        XPopup.Builder(context)
            .isDestroyOnDismiss(true)
            .asCustom(
                CommonSureDetailDialog(
                    context = context,
                    mTitle = StringUtils.getString(string.authorization_prompts),
                    mDetail = StringUtils.getString(string.prompts_please_open),
                    mConfirmText = StringUtils.getString(string.go_to_settings),
                    mOnSetClick = {
                        val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
                        val uri = Uri.fromParts(
                            "package",
                            context.packageName,
                            null
                        )
                        intent.data = uri
                        ActivityUtils.startActivity(intent)
                    })
            ).show()

    }

}

/**
 * 选中类
 */
data class SelectMusicBean(
    val music: MusicBean,
    var select: Boolean,
    var haveSelect: Boolean,
)
